package com.ca.ridersclubapplication.request;

import android.app.Activity;
import android.widget.Toast;

import androidx.annotation.NonNull;

import com.ca.ridersclubapplication.data.DataHandler;
import com.ca.ridersclubapplication.data.entity.BooleanEntity;
import com.ca.ridersclubapplication.request.dto.CommentDto;
import com.ca.ridersclubapplication.data.entity.ListEntity;
import com.ca.ridersclubapplication.data.entity.LongEntity;
import com.ca.ridersclubapplication.request.dto.HistoryDto;
import com.ca.ridersclubapplication.request.dto.PaperCardDto;
import com.ca.ridersclubapplication.request.dto.PaperInfoDto;
import com.ca.ridersclubapplication.data.entity.Token;
import com.ca.ridersclubapplication.request.dto.Result;

import java.util.List;

import retrofit2.Call;
import retrofit2.Response;
import retrofit2.Retrofit;
import retrofit2.converter.gson.GsonConverterFactory;
import retrofit2.http.Field;
import retrofit2.http.FormUrlEncoded;
import retrofit2.http.GET;
import retrofit2.http.Header;
import retrofit2.http.POST;
import retrofit2.http.Query;

public class PaperRequester {

    public static final String URL = "paper/";
    public static final PaperAPI api;

    static {
        api = new Retrofit.Builder()
                .baseUrl(Config.BASE_URL + URL)
                .addConverterFactory(GsonConverterFactory.create())
                .build()
                .create(PaperAPI.class);
    }

    public interface PaperAPI {

        @GET("getById")
        Call<Result<PaperInfoDto>> getPaperById(@Query("paperId") Long paperId);

        @GET("search")
        Call<Result<List<PaperCardDto>>> search(
                @Query("keyword") String keyword,
                @Query("startId") Long startId);

        @GET("get")
        Call<Result<List<PaperCardDto>>> getPapers(
                @Query("accountId") Long accountId,
                @Query("startId") Long startId);

        @GET("all")
        Call<Result<List<PaperCardDto>>> getPapers();

        @GET("getByClubId")
        Call<Result<List<PaperCardDto>>> getPapersByClubId(
                @Query("clubId") Long clubId,
                @Query("startId") Long startId);

        @POST("add")
        @FormUrlEncoded
        Call<Result<String>> addPaper(
                @Field("title") String title,
                @Field("connect") String connect,
                @Field("clubId") Long clubId,
                @Header("Authorization") String token,
                @Header("arg0") String hid,
                @Header("arg1") String email);

        @POST("delete")
        @FormUrlEncoded
        Call<Result<String>> deletePaper(
                @Field("paperId") Long paperId,
                @Header("Authorization") String token,
                @Header("arg0") String hid,
                @Header("arg1") String email);

        @GET("getLastPaper")
        Call<Result<PaperCardDto>> getLastPaper(@Query("accountId") Long accountId);

        @GET("getLastCommentForPaper")
        Call<Result<CommentDto>> getLastCommentForPaper(
                @Query("accountId") Long accountId,
                @Query("paperId") Long paperId);

        @GET("isSupport")
        Call<Result<Boolean>> isSupport(
                @Query("paperId") Long paperId,
                @Header("Authorization") String token,
                @Header("arg0") String hid,
                @Header("arg1") String email);

        @GET("supportCount")
        Call<Result<Long>> getSupportCount(@Query("paperId") Long paperId);

        @POST("addSupport")
        @FormUrlEncoded
        Call<Result<String>> addSupport(
                @Field("paperId") Long paperId,
                @Header("Authorization") String token,
                @Header("arg0") String hid,
                @Header("arg1") String email);

        @POST("deleteSupport")
        @FormUrlEncoded
        Call<Result<String>> deleteSupport(
                @Field("paperId") Long paperId,
                @Header("Authorization") String token,
                @Header("arg0") String hid,
                @Header("arg1") String email);

        @POST("supportComment")
        @FormUrlEncoded
        Call<Result<String>> supportComment(
                @Field("commentId") Long commentId,
                @Header("Authorization") String token,
                @Header("arg0") String hid,
                @Header("arg1") String email);

        @POST("deleteSupportComment")
        @FormUrlEncoded
        Call<Result<String>> deleteSupportComment(
                @Field("commentId") Long commentId,
                @Header("Authorization") String token,
                @Header("arg0") String hid,
                @Header("arg1") String email);

        @GET("isSupportComment")
        Call<Result<Boolean>> isSupportComment(
                @Query("commentId") Long commentId,
                @Header("Authorization") String token,
                @Header("arg0") String hid,
                @Header("arg1") String email);

        @GET("getCommentsByPaperAndAccount")
        Call<Result<List<CommentDto>>> getCommentsByPaperAndAccount(
                @Query("paperId") Long paperId,
                @Query("accountId") Long accountId);

        @GET("getCommentByPaper")
        Call<Result<List<CommentDto>>> getCommentsByPaper(
                @Query("paperId") Long paperId,
                @Query("startId") Long startId);

        @POST("addComment")
        @FormUrlEncoded
        Call<Result<String>> addComment(
                @Field("content") String content,
                @Field("paperId") Long paperId,
                @Header("Authorization") String token,
                @Header("arg0") String hid,
                @Header("arg1") String email);

        @POST("deleteComment")
        @FormUrlEncoded
        Call<Result<String>> deleteComment(
                @Field("commentId") Long commentId,
                @Header("Authorization") String token,
                @Header("arg0") String hid,
                @Header("arg1") String email);

        @GET("commentCount")
        Call<Result<Long>> getCommentCount(@Query("paperId") Long paperId);

        @POST("addHistory")
        @FormUrlEncoded
        Call<Result<String>> addHistory(
                @Field("paperId") Long paperId,
                @Header("Authorization") String token,
                @Header("arg0") String hid,
                @Header("arg1") String email);

        @GET("listHistory")
        Call<Result<List<HistoryDto>>> listHistory(
                @Query("startId") Long startId,
                @Header("Authorization") String token,
                @Header("arg0") String hid,
                @Header("arg1") String email);
    }

    public static void getById(Activity activity, Long paperId, AfterExecutor<PaperInfoDto> executor) {
        api.getPaperById(paperId).enqueue(new APICallback<>(activity, executor));
    }

    public static void listPaperByKeyword(Activity activity, String keyword, Long startId, AfterExecutor<List<PaperCardDto>> executor) {
        api.search(keyword, startId)
                .enqueue(new APICallback<List<PaperCardDto>>(activity, executor) {
                    @Override
                    public void onResponse(@NonNull Call<Result<List<PaperCardDto>>> call, @NonNull Response<Result<List<PaperCardDto>>> response) {
                        super.onResponse(call, response);
                        if (isSuccess()) {
                            DataHandler.putData(new ListEntity<>(
                                    "PaperList:Keyword",
                                    getData()));
                        }
                    }
                });
    }

    public static void listPaperByAccountId(Activity activity, Long accountId, Long startId, AfterExecutor<List<PaperCardDto>> executor) {
        api.getPapers(accountId, startId)
                .enqueue(new APICallback<List<PaperCardDto>>(activity, executor) {
                    @Override
                    public void onResponse(@NonNull Call<Result<List<PaperCardDto>>> call, @NonNull Response<Result<List<PaperCardDto>>> response) {
                        super.onResponse(call, response);
                        if (isSuccess()) {
                            DataHandler.putData(new ListEntity<>(
                                    "PaperListByAccountId:" + accountId + ":" + startId,
                                    getData()));
                        }
                    }
                });
    }

    public static void listPaperByClubId(Activity activity, Long clubId, Long startId, AfterExecutor<List<PaperCardDto>> executor) {
        api.getPapersByClubId(clubId, startId)
                .enqueue(new APICallback<List<PaperCardDto>>(activity, executor) {
                    @Override
                    public void onResponse(@NonNull Call<Result<List<PaperCardDto>>> call, @NonNull Response<Result<List<PaperCardDto>>> response) {
                        super.onResponse(call, response);
                        if (isSuccess()) {
                            DataHandler.putData(new ListEntity<>(
                                    "PaperListByClubId:" + clubId + ":" + startId,
                                    getData()));
                        }
                    }
                });
    }

    public static void addPaper(Activity activity, String title, String content, Long clubId, AfterExecutor<String> executor) {
        Token token = DataHandler.getToken(activity);
        api.addPaper(title, content, clubId, token.getToken(), String.valueOf(token.getId()), token.getEmail())
                .enqueue(new APICallback<>(activity, executor));
    }

    public static void deletePaper(Activity activity, Long paperId, AfterExecutor<String> executor) {
        Token token = DataHandler.getToken(activity);
        api.deletePaper(paperId, token.getToken(), String.valueOf(token.getId()), token.getEmail())
                .enqueue(new APICallback<String>(activity, executor) {
                    @Override
                    public void onResponse(@NonNull Call<Result<String>> call, @NonNull Response<Result<String>> response) {
                        super.onResponse(call, response);
                        if (isSuccess()) {
                            DataHandler.putData(new BooleanEntity("AddHistory", true));
                        }
                    }
                });
    }

    public static void isSupport(Activity activity, Long paperId, AfterExecutor<Boolean> executor) {
        Token token = DataHandler.getToken(activity);
        api.isSupport(paperId, token.getToken(), String.valueOf(token.getId()), token.getEmail())
                .enqueue(new APICallback<Boolean>(activity, executor) {
                    @Override
                    public void onResponse(@NonNull Call<Result<Boolean>> call, @NonNull Response<Result<Boolean>> response) {
                        super.onResponse(call, response);
                        if (isSuccess()) {
                            DataHandler.putData(new BooleanEntity("PaperIsSupport:" + paperId, getData()));
                        }
                    }
                });
    }

    public static void getSupportCount(Activity activity, Long paperId, AfterExecutor<Long> executor) {
        api.getSupportCount(paperId)
                .enqueue(new APICallback<Long>(activity, executor) {
                    @Override
                    public void onResponse(@NonNull Call<Result<Long>> call, @NonNull Response<Result<Long>> response) {
                        super.onResponse(call, response);
                        if (isSuccess()) {
                            DataHandler.putData(new LongEntity("PaperSupportCount:" + paperId, getData()));
                        }
                    }
                });
    }

    public static void addSupport(Activity activity, Long paperId, AfterExecutor<String> executor) {
        Token token = DataHandler.getToken(activity);
        api.addSupport(paperId, token.getToken(), String.valueOf(token.getId()), token.getEmail())
                .enqueue(new APICallback<>(activity, executor));
    }

    public static void deleteSupport(Activity activity, Long paperId, AfterExecutor<String> executor) {
        Token token = DataHandler.getToken(activity);
        api.deleteSupport(paperId, token.getToken(), String.valueOf(token.getId()), token.getEmail())
                .enqueue(new APICallback<>(activity, executor));
    }

    public static void listCommentByPaperId(Activity activity, Long paperId, Long startId, AfterExecutor<List<CommentDto>> executor) {
        api.getCommentsByPaper(paperId, startId)
                .enqueue(new APICallback<List<CommentDto>>(activity, executor) {
                    @Override
                    public void onResponse(@NonNull Call<Result<List<CommentDto>>> call, @NonNull Response<Result<List<CommentDto>>> response) {
                        super.onResponse(call, response);
                        if (isSuccess()) {
                            DataHandler.putData(new ListEntity<>(
                                    "CommentListByPaperId:" + paperId + ":" + startId,
                                    getData()));
                        }
                    }
                });
    }

    public static void addComment(Activity activity, Long paperId, String content, AfterExecutor<String> executor) {
        Token token = DataHandler.getToken(activity);
        api.addComment(content, paperId, token.getToken(), String.valueOf(token.getId()), token.getEmail())
                .enqueue(new APICallback<>(activity, executor));
    }

    public static void deleteComment(Activity activity, Long commentId, AfterExecutor<String> executor) {
        Token token = DataHandler.getToken(activity);
        api.deleteComment(commentId, token.getToken(), String.valueOf(token.getId()), token.getEmail())
                .enqueue(new APICallback<String>(activity, executor) {
                    @Override
                    public void onResponse(@NonNull Call<Result<String>> call, @NonNull Response<Result<String>> response) {
                        super.onResponse(call, response);
                        if (isSuccess()) {
                            Toast.makeText(getActivity(), "删除成功", Toast.LENGTH_SHORT).show();
                        }
                    }
                });
    }

    public static void getCommentCount(Activity activity, Long paperId, AfterExecutor<Long> executor) {
        api.getCommentCount(paperId)
                .enqueue(new APICallback<Long>(activity, executor) {
                    @Override
                    public void onResponse(@NonNull Call<Result<Long>> call, @NonNull Response<Result<Long>> response) {
                        super.onResponse(call, response);
                        if (isSuccess()) {
                            DataHandler.putData(new LongEntity("PaperCommentCount:" + paperId, getData()));
                        }
                    }
                });
    }

    public static void listPapers(Activity activity, AfterExecutor<List<PaperCardDto>> executor) {
        api.getPapers().enqueue(new APICallback<List<PaperCardDto>>(activity, executor) {
            @Override
            public void onResponse(@NonNull Call<Result<List<PaperCardDto>>> call, @NonNull Response<Result<List<PaperCardDto>>> response) {
                super.onResponse(call, response);
                if (isSuccess()) {
                    //  请求成功，将数据追加到数据处理器中
                    DataHandler.appendListData(new ListEntity<>("PaperList:Main", getData()));
                }
            }
        });
    }

    public static void getLastPaper(Activity activity, Long accountId, AfterExecutor<PaperCardDto> executor) {
        api.getLastPaper(accountId).enqueue(new APICallback<>(activity, executor));
    }

    public static void supportComment(Activity activity, Long commentId, AfterExecutor<String> executor) {
        Token token = DataHandler.getToken(activity);
        api.supportComment(commentId, token.getToken(), String.valueOf(token.getId()), token.getEmail())
                .enqueue(new APICallback<>(activity, executor));
    }

    public static void deleteSupportComment(Activity activity, Long commentId, AfterExecutor<String> executor) {
        Token token = DataHandler.getToken(activity);
        api.deleteSupportComment(commentId, token.getToken(), String.valueOf(token.getId()), token.getEmail())
                .enqueue(new APICallback<>(activity, executor));
    }

    public static void isSupportComment(Activity activity, Long commentId, AfterExecutor<Boolean> executor) {
        Token token = DataHandler.getToken(activity);
        api.isSupportComment(commentId, token.getToken(), String.valueOf(token.getId()), token.getEmail())
                .enqueue(new APICallback<>(activity, executor));
    }

    public static void getLastCommentForPaper(Activity activity, Long paperId, AfterExecutor<CommentDto> executor) {
        Token token = DataHandler.getToken(activity);
        api.getLastCommentForPaper(token.getId(), paperId)
                .enqueue(new APICallback<>(activity, executor));
    }

    public static void addHistory(Activity activity, Long paperId, AfterExecutor<String> executor) {
        Token token = DataHandler.getToken(activity);
        api.addHistory(paperId, token.getToken(), String.valueOf(token.getId()), token.getEmail())
                .enqueue(new APICallback<>(activity, executor));
    }

    public static void listHistory(Activity activity, Long startId, AfterExecutor<List<HistoryDto>> executor) {
        Token token = DataHandler.getToken(activity);
        api.listHistory(startId, token.getToken(), String.valueOf(token.getId()), token.getEmail())
                .enqueue(new APICallback<>(activity, executor));
    }
}
